import java.util.ArrayList;

import sharedClasses.Action;
import sharedClasses.Play;

//This class crunches data to look for patterns
public class Engine
{
	//A debugging method to print out heat maps
	public static void printInput(int[][] input)
	{
		for (int j = 0; j < input[0].length; j++)
		{
			for (int i = 0; i < input.length; i++)
			{
				System.out.print(input[i][j] + "\t");
			}
			if (j == 29)
			{
				System.out.print("\n-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------");
			}
			System.out.println();
		}
		
	}
	
	//A debugging method to print out weight maps
	public static void printInput(double[][] input)
	{
		for (int j = 0; j < input[0].length; j++)
		{
			for (int i = 0; i < input.length; i++)
			{
				System.out.printf("%.3f\t", input[i][j]);
			}
			if (j == 29)
			{
				System.out.print("\n-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------");
			}
			System.out.println();
		}
		
	}
	
	//Converts an array of coordinates into a weight map
	public static int[][] convertCoordsToWeightMap(int[][] coords)
	{
		int[][] map = null;
		
		map = new int[Court.RIGHT_ZONE_END][Court.COURT_END];
		for (int i = 0; i < map.length; i++)
		{
			for (int j = 0; j < map[i].length; j++)
			{
				map[i][j] = 0;
			}
		}
		
		for (int i = 0; i < coords.length; i++)
		{
			//Increment each cell in the coordinate array
			int x = coords[i][0];
			int y = coords[i][1];
			map[x][y]++;
		}
		
		return map;
	}
	
	//Takes a weightmap, and creates a hotmap
	public static double[][] findHotspots(int[][] map, int precision)
	{		
		double[][] hotspotMap = new double[map.length][map[0].length];
		
		for (int i = 0; i < map.length; i++)
		{
			for (int j = 0; j < map[0].length; j++)
			{
				double count = 0;
				for (int k = -1 * precision; k <= precision; k++)
				{
					for (int l = -1 * precision; l <= precision; l++)
					{
						if (((i + k) >= 0) && ((i + k) < map.length)
								&& ((j + l) >=0) && ((j + l) < map[0].length))
						{
							if ((j < Court.MID_LINE) && ((j + l) < Court.MID_LINE)
									|| ((j >= Court.MID_LINE) && ((j + l) >= Court.MID_LINE)))
							{
								double coefficient = 0;
								if ((Math.abs(k) >= Math.abs(l)))
								{
									coefficient = 1. / (Math.pow(2, Math.abs(k)));
								}
								else
								{
									coefficient = 1. / (Math.pow(2, Math.abs(l)));
								}
								count += coefficient * map[i + k][j + l];
							}
						}
					}
				}
				hotspotMap[i][j] = count;
			}
		}
		
		return hotspotMap;
	}
	
	//Find the strongest play for the home team
	public static Play findStrongestPattern(Play[] plays)
	{
		return findPatternWithResult(plays, 1);
	}
	
	//Find the strongest play for the opposing team
	public static Play findWeakestPattern(Play[] plays)
	{
		return findPatternWithResult(plays, -1);
	}
	
	//Find the most common response to the home team's serves, regardless of the outcome
	public static Play findOpponentServeReceivePatterns(Play[] plays)
	{
		int searchRadius = 5;
		ArrayList<Play> tempPlays = new ArrayList<Play>();
		for (int i = 0; i < plays.length; i++)
		{
			tempPlays.add(plays[i]);
		}
		
		//Find the places that passes happen most often
		int[][] serveCoords = new int[tempPlays.size()][2];
		for (int i = 0; i < tempPlays.size(); i++)
		{
			int[] origin = tempPlays.get(i).Children.get(0).getOrigin();
			serveCoords[i][0] = origin[0];
			serveCoords[i][1] = origin[1];
		}
		double[][] serveHotMap = findHotspots(convertCoordsToWeightMap(serveCoords), searchRadius);
		
		//Identify the hottest areas
		double maxIntensity = 0;
		ArrayList<int[]> hotServeCoords = new ArrayList<int[]>();
		for (int i = 0; i < serveHotMap.length; i++)
		{
			for (int j = 0; j < serveHotMap[i].length; j++)
			{
				if (serveHotMap[i][j] > maxIntensity)
				{
					hotServeCoords.clear();
					int[] coord = {i, j};
					hotServeCoords.add(coord);
					maxIntensity = serveHotMap[i][j];
				}
				else if (serveHotMap[i][j] == maxIntensity)
				{
					int[] coord = {i, j};
					hotServeCoords.add(coord);
				}
			}
		}
		
		//Search around the hot areas for actual plays
		boolean[] playFound = new boolean[tempPlays.size()];
		for (int n = 0; n < hotServeCoords.size(); n++)
		{
			for (int i = -1 * searchRadius; i <= searchRadius; i++)
			{
				for (int j = -1 * searchRadius; j <= searchRadius; j++)
				{
					for (int iPlay = 0; iPlay < tempPlays.size(); iPlay++)
					{
						int[] origin = tempPlays.get(iPlay).Children.get(0).getOrigin();
						if ((hotServeCoords.get(n)[0] + i == origin[0]) && (hotServeCoords.get(n)[1] + j == origin[1]))
						{
							playFound[iPlay] = true;
						}
					}
				}
			}
		}
		
		//Remove plays that were not found in the search radius
		for (int i = 0; i < tempPlays.size(); i++)
		{
			if (!playFound[i])
			{
				tempPlays.remove(i);
			}
		}
		
		//Find the places that passes happen most often
		int[][] passCoords = new int[tempPlays.size()][2];
		for (int i = 0; i < tempPlays.size(); i++)
		{
			if (tempPlays.get(i).Children.size() >= 2)
			{
				int[] origin = tempPlays.get(i).Children.get(1).getOrigin();
				passCoords[i][0] = origin[0];
				passCoords[i][1] = origin[1];
			}
		}
		double[][] passHotMap = findHotspots(convertCoordsToWeightMap(passCoords), searchRadius);
		
		//Identify the hottest areas
		maxIntensity = 0;
		ArrayList<int[]> hotPassCoords = new ArrayList<int[]>();
		for (int i = 0; i < passHotMap.length; i++)
		{
			for (int j = 0; j < passHotMap[i].length; j++)
			{
				if (passHotMap[i][j] > maxIntensity)
				{
					hotPassCoords.clear();
					int[] coord = {i, j};
					hotPassCoords.add(coord);
					maxIntensity = passHotMap[i][j];
				}
				else if (passHotMap[i][j] == maxIntensity)
				{
					int[] coord = {i, j};
					hotPassCoords.add(coord);
				}
			}
		}
		
		//Search around the hot areas for actual plays
		playFound = new boolean[tempPlays.size()];
		for (int n = 0; n < hotPassCoords.size(); n++)
		{
			for (int i = -1 * searchRadius; i <= searchRadius; i++)
			{
				for (int j = -1 * searchRadius; j <= searchRadius; j++)
				{
					for (int iPlay = 0; iPlay < tempPlays.size(); iPlay++)
					{
						if (tempPlays.get(iPlay).Children.size() >= 2)
						{
							int[] origin = tempPlays.get(iPlay).Children.get(1).getOrigin();
							if ((hotPassCoords.get(n)[0] + i == origin[0]) && (hotPassCoords.get(n)[1] + j == origin[1]))
							{
								playFound[iPlay] = true;
							}
						}
					}
				}
			}
		}
		
		//Remove plays that were not found in the search radius
		for (int i = 0; i < tempPlays.size(); i++)
		{
			if (!playFound[i])
			{
				tempPlays.remove(i);
			}
		}
		
		//Find the places that passes happen most often
		int[][] setCoords = new int[tempPlays.size()][2];
		for (int i = 0; i < tempPlays.size(); i++)
		{
			if (tempPlays.get(i).Children.size() >= 3)
			{
				int[] origin = tempPlays.get(i).Children.get(2).getOrigin();
				setCoords[i][0] = origin[0];
				setCoords[i][1] = origin[1];
			}
		}
		double[][] setHotMap = findHotspots(convertCoordsToWeightMap(setCoords), searchRadius);
		
		//Identify the hottest areas
		maxIntensity = 0;
		ArrayList<int[]> hotSetCoords = new ArrayList<int[]>();
		for (int i = 0; i < setHotMap.length; i++)
		{
			for (int j = 0; j < setHotMap[i].length; j++)
			{
				if (setHotMap[i][j] > maxIntensity)
				{
					hotSetCoords.clear();
					int[] coord = {i, j};
					hotSetCoords.add(coord);
					maxIntensity = setHotMap[i][j];
				}
				else if (setHotMap[i][j] == maxIntensity)
				{
					int[] coord = {i, j};
					hotSetCoords.add(coord);
				}
			}
		}
		
		//Search around the hot areas for actual plays
		playFound = new boolean[tempPlays.size()];
		for (int n = 0; n < hotSetCoords.size(); n++)
		{
			for (int i = -1 * searchRadius; i <= searchRadius; i++)
			{
				for (int j = -1 * searchRadius; j <= searchRadius; j++)
				{
					for (int iPlay = 0; iPlay < tempPlays.size(); iPlay++)
					{
						if (tempPlays.get(iPlay).Children.size() >= 3)
						{
							int[] origin = tempPlays.get(iPlay).Children.get(2).getOrigin();
							if ((hotSetCoords.get(n)[0] + i == origin[0]) && (hotSetCoords.get(n)[1] + j == origin[1]))
							{
								playFound[iPlay] = true;
							}
						}
					}
				}
			}
		}
		
		//Remove plays that were not found in the search radius
		for (int i = 0; i < tempPlays.size(); i++)
		{
			if (!playFound[i])
			{
				tempPlays.remove(i);
			}
		}
		
		//Find the places that passes happen most often
		int[][] hitCoords = new int[tempPlays.size()][2];
		for (int i = 0; i < tempPlays.size(); i++)
		{
			if (tempPlays.get(i).Children.size() >= 4)
			{
				int[] origin = tempPlays.get(i).Children.get(3).getOrigin();
				hitCoords[i][0] = origin[0];
				hitCoords[i][1] = origin[1];
			}
		}
		double[][] hitHotMap = findHotspots(convertCoordsToWeightMap(hitCoords), searchRadius);
		
		//Identify the hottest areas
		maxIntensity = 0;
		ArrayList<int[]> hotHitCoords = new ArrayList<int[]>();
		for (int i = 0; i < hitHotMap.length; i++)
		{
			for (int j = 0; j < hitHotMap[i].length; j++)
			{
				if (hitHotMap[i][j] > maxIntensity)
				{
					hotHitCoords.clear();
					int[] coord = {i, j};
					hotHitCoords.add(coord);
					maxIntensity = hitHotMap[i][j];
				}
				else if (hitHotMap[i][j] == maxIntensity)
				{
					int[] coord = {i, j};
					hotHitCoords.add(coord);
				}
			}
		}
		
		//Search around the hot areas for actual plays
		playFound = new boolean[tempPlays.size()];
		for (int n = 0; n < hotHitCoords.size(); n++)
		{
			for (int i = -1 * searchRadius; i <= searchRadius; i++)
			{
				for (int j = -1 * searchRadius; j <= searchRadius; j++)
				{
					for (int iPlay = 0; iPlay < tempPlays.size(); iPlay++)
					{
						if (tempPlays.get(iPlay).Children.size() >= 4)
						{
							int[] origin = tempPlays.get(iPlay).Children.get(3).getOrigin();
							if ((hotHitCoords.get(n)[0] + i == origin[0]) && (hotHitCoords.get(n)[1] + j == origin[1]))
							{
								playFound[iPlay] = true;
							}
						}
					}
				}
			}
		}
		
		//Remove plays that were not found in the search radius
		for (int i = 0; i < tempPlays.size(); i++)
		{
			if (!playFound[i])
			{
				tempPlays.remove(i);
			}
		}
		
		//Find the places that passes happen most often
		int[][] killCoords = new int[tempPlays.size()][2];
		for (int i = 0; i < tempPlays.size(); i++)
		{
			if (tempPlays.get(i).Children.size() >= 4)
			{
				int[] origin = tempPlays.get(i).Children.get(3).getDestination();
				killCoords[i][0] = origin[0];
				killCoords[i][1] = origin[1];
			}
		}
		double[][] killHotMap = findHotspots(convertCoordsToWeightMap(killCoords), searchRadius);
		
		//Identify the hottest areas
		maxIntensity = 0;
		ArrayList<int[]> hotKillCoords = new ArrayList<int[]>();
		for (int i = 0; i < killHotMap.length; i++)
		{
			for (int j = 0; j < killHotMap[i].length; j++)
			{
				if (killHotMap[i][j] > maxIntensity)
				{
					hotKillCoords.clear();
					int[] coord = {i, j};
					hotKillCoords.add(coord);
					maxIntensity = killHotMap[i][j];
				}
				else if (killHotMap[i][j] == maxIntensity)
				{
					int[] coord = {i, j};
					hotKillCoords.add(coord);
				}
			}
		}
		
		//Search around the hot areas for actual plays
		playFound = new boolean[tempPlays.size()];
		for (int n = 0; n < hotKillCoords.size(); n++)
		{
			for (int i = -1 * searchRadius; i <= searchRadius; i++)
			{
				for (int j = -1 * searchRadius; j <= searchRadius; j++)
				{
					for (int iPlay = 0; iPlay < tempPlays.size(); iPlay++)
					{
						if (tempPlays.get(iPlay).Children.size() >= 4)
						{
							int[] destination = tempPlays.get(iPlay).Children.get(3).getDestination();
							if ((hotKillCoords.get(n)[0] + i == destination[0]) && (hotKillCoords.get(n)[1] + j == destination[1]))
							{
								playFound[iPlay] = true;
							}
						}
					}
				}
			}
		}
		
		//Remove plays that were not found in the search radius
		for (int i = 0; i < tempPlays.size(); i++)
		{
			if (!playFound[i])
			{
				tempPlays.remove(i);
			}
		}
		
		if (tempPlays.size() == 0)
		{
			return null;
		}
		
		//Now average the locations to get the pattern skeleton
		int[][] patternCoords = new int[4][2];
		int[] point0 = {0, 0};
		int[] point1 = {0, 0};
		int[] point2 = {0, 0};
		int[] point3 = {0, 0};
		int[] point4 = {0, 0};
		for (int i = 0; i < tempPlays.size(); i++)
		{
			point0[0] += tempPlays.get(i).Children.get(tempPlays.get(i).Children.size() - 4).getOrigin()[0];
			point0[1] += tempPlays.get(i).Children.get(tempPlays.get(i).Children.size() - 4).getOrigin()[1];
			point1[0] += tempPlays.get(i).Children.get(tempPlays.get(i).Children.size() - 3).getOrigin()[0];
			point1[1] += tempPlays.get(i).Children.get(tempPlays.get(i).Children.size() - 3).getOrigin()[1];
			point2[0] += tempPlays.get(i).Children.get(tempPlays.get(i).Children.size() - 2).getOrigin()[0];
			point2[1] += tempPlays.get(i).Children.get(tempPlays.get(i).Children.size() - 2).getOrigin()[1];
			point3[0] += tempPlays.get(i).Children.get(tempPlays.get(i).Children.size() - 1).getOrigin()[0];
			point3[1] += tempPlays.get(i).Children.get(tempPlays.get(i).Children.size() - 1).getOrigin()[1];
			point4[0] += tempPlays.get(i).Children.get(tempPlays.get(i).Children.size() - 1).getDestination()[0];
			point4[1] += tempPlays.get(i).Children.get(tempPlays.get(i).Children.size() - 1).getDestination()[1];
		}
		point0[0] /= tempPlays.size();
		point0[1] /= tempPlays.size();
		point1[0] /= tempPlays.size();
		point1[1] /= tempPlays.size();
		point2[0] /= tempPlays.size();
		point2[1] /= tempPlays.size();
		point3[0] /= tempPlays.size();
		point3[1] /= tempPlays.size();
		point4[0] /= tempPlays.size();
		point4[1] /= tempPlays.size();
		
		
		ArrayList<Action> actions = new ArrayList<Action>();
		actions.add(new Action (point1, point2, 0));
		actions.add(new Action (point2, point3, 0));
		actions.add(new Action (point3, point4, -1));
		Play play = new Play();
		play.Children = actions;
//		patternCoords[0][0] = point1[0];
//		patternCoords[0][1] = point1[1];
//		patternCoords[1][0] = point2[0];
//		patternCoords[1][1] = point2[1];
//		patternCoords[2][0] = point3[0];
//		patternCoords[2][1] = point3[1];
//		patternCoords[3][0] = point4[0];
//		patternCoords[3][1] = point4[1];
		
		return play;
		
	}
	
	
	
	//Find the strongest/weakest patterns. The playResult is used to specify which team we should be looking for patterns for
	private static Play findPatternWithResult(Play[] plays, int playResult)
	{
		int searchRadius = 5;
		
		//Get all the plays with playResult
		ArrayList<Play> tempPlays = new ArrayList<Play>();
		for (int i = 0; i < plays.length; i++)
		{
			if (plays[i].getResult() == playResult)
			{
				tempPlays.add(plays[i]);
			}
		}
		
		//Find the places that kills happen most often
		int[][] killCoords = new int[tempPlays.size()][2];
		for (int i = 0; i < tempPlays.size(); i++)
		{
			int[] destination = tempPlays.get(i).Children.get(tempPlays.get(i).Children.size() - 1).getDestination();
			killCoords[i][0] = destination[0];
			killCoords[i][1] = destination[1];
		}
		double[][] killHotMap = findHotspots(convertCoordsToWeightMap(killCoords), searchRadius);
		
		//Identify the hottest areas
		double maxIntensity = 0;
		ArrayList<int[]> hotKillCoords = new ArrayList<int[]>();
		for (int i = 0; i < killHotMap.length; i++)
		{
			for (int j = 0; j < killHotMap[i].length; j++)
			{
				if (killHotMap[i][j] > maxIntensity)
				{
					hotKillCoords.clear();
					int[] coord = {i, j};
					hotKillCoords.add(coord);
					maxIntensity = killHotMap[i][j];
				}
				else if (killHotMap[i][j] == maxIntensity)
				{
					int[] coord = {i, j};
					hotKillCoords.add(coord);
				}
			}
		}
		
		//Search around the hot areas for actual plays
		boolean[] playFound = new boolean[tempPlays.size()];
		for (int n = 0; n < hotKillCoords.size(); n++)
		{
			for (int i = -1 * searchRadius; i <= searchRadius; i++)
			{
				for (int j = -1 * searchRadius; j <= searchRadius; j++)
				{
					for (int iPlay = 0; iPlay < tempPlays.size(); iPlay++)
					{
						int[] destination = tempPlays.get(iPlay).Children.get(tempPlays.get(iPlay).Children.size() - 1).getDestination();
						if ((hotKillCoords.get(n)[0] + i == destination[0]) && (hotKillCoords.get(n)[1] + j == destination[1]))
						{
							playFound[iPlay] = true;
						}
					}
				}
			}
		}
		
		//Remove plays that were not found in the search radius
		for (int i = 0; i < tempPlays.size(); i++)
		{
			if (!playFound[i])
			{
				tempPlays.remove(i);
			}
		}
		
		
		
		//Find the places that hits happen most often
		int[][] hitCoords = new int[tempPlays.size()][2];
		for (int i = 0; i < tempPlays.size(); i++)
		{
			int[] origin = tempPlays.get(i).Children.get(tempPlays.get(i).Children.size() - 1).getOrigin();
			hitCoords[i][0] = origin[0];
			hitCoords[i][1] = origin[1];
		}
		double[][] hitHotMap = findHotspots(convertCoordsToWeightMap(hitCoords), searchRadius + 1);
		
		//Identify the hottest areas
		maxIntensity = 0;
		ArrayList<int[]> hotHitCoords = new ArrayList<int[]>();
		for (int i = 0; i < hitHotMap.length; i++)
		{
			for (int j = 0; j < hitHotMap[i].length; j++)
			{
				if (hitHotMap[i][j] > maxIntensity)
				{
					hotHitCoords.clear();
					int[] coord = {i, j};
					hotHitCoords.add(coord);
					maxIntensity = hitHotMap[i][j];
				}
				else if (hitHotMap[i][j] == maxIntensity)
				{
					int[] coord = {i, j};
					hotHitCoords.add(coord);
				}
			}
		}
		
		//Search around the hot areas for actual plays
		playFound = new boolean[tempPlays.size()];
		for (int n = 0; n < hotHitCoords.size(); n++)
		{
			for (int i = -1 * searchRadius; i <= searchRadius; i++)
			{
				for (int j = -1 * searchRadius; j <= searchRadius; j++)
				{
					for (int iPlay = 0; iPlay < tempPlays.size(); iPlay++)
					{
						int[] origin = tempPlays.get(iPlay).Children.get(tempPlays.get(iPlay).Children.size() - 1).getOrigin();
						if ((hotHitCoords.get(n)[0] + i == origin[0]) && (hotHitCoords.get(n)[1] + j == origin[1]))
						{
							playFound[iPlay] = true;
						}
					}
				}
			}
		}
		
		//Remove plays that were not found in the search radius
		for (int i = 0; i < tempPlays.size(); i++)
		{
			if (!playFound[i])
			{
				tempPlays.remove(i);
			}
		}
		
		
		
		
		
		//Find the places that sets happen most often
		int[][] setCoords = new int[tempPlays.size()][2];
		for (int i = 0; i < tempPlays.size(); i++)
		{
			if (tempPlays.get(i).Children.size() - 2 >= 0)
			{
				int[] origin = tempPlays.get(i).Children.get(tempPlays.get(i).Children.size() - 2).getOrigin();
				setCoords[i][0] = origin[0];
				setCoords[i][1] = origin[1];
			}
		}
		double[][] setHotMap = findHotspots(convertCoordsToWeightMap(setCoords), searchRadius + 2);
		
		//Identify the hottest areas
		maxIntensity = 0;
		ArrayList<int[]> hotSetCoords = new ArrayList<int[]>();
		for (int i = 0; i < setHotMap.length; i++)
		{
			for (int j = 0; j < setHotMap[i].length; j++)
			{
				if (setHotMap[i][j] > maxIntensity)
				{
					hotSetCoords.clear();
					int[] coord = {i, j};
					hotSetCoords.add(coord);
					maxIntensity = setHotMap[i][j];
				}
				else if (setHotMap[i][j] == maxIntensity)
				{
					int[] coord = {i, j};
					hotSetCoords.add(coord);
				}
			}
		}
		
		//Search around the hot areas for actual plays
		playFound = new boolean[tempPlays.size()];
		for (int n = 0; n < hotSetCoords.size(); n++)
		{
			for (int i = -1 * searchRadius; i <= searchRadius; i++)
			{
				for (int j = -1 * searchRadius; j <= searchRadius; j++)
				{
					for (int iPlay = 0; iPlay < tempPlays.size(); iPlay++)
					{
						if (tempPlays.get(iPlay).Children.size() - 2 >= 0)
						{
							int[] origin = tempPlays.get(iPlay).Children.get(tempPlays.get(iPlay).Children.size() - 2).getOrigin();
							if ((hotSetCoords.get(n)[0] + i == origin[0]) && (hotSetCoords.get(n)[1] + j == origin[1]))
							{
								playFound[iPlay] = true;
							}
						}
					}
				}
			}
		}
		
		//Remove plays that were not found in the search radius
		for (int i = 0; i < tempPlays.size(); i++)
		{
			if (!playFound[i])
			{
				tempPlays.remove(i);
			}
		}
		
		
		
		
		//Find the places that passes happen most often
		int[][] passCoords = new int[tempPlays.size()][2];
		for (int i = 0; i < tempPlays.size(); i++)
		{
			if (tempPlays.get(i).Children.size() - 3 >= 0)
			{
				int[] origin = tempPlays.get(i).Children.get(tempPlays.get(i).Children.size() - 3).getOrigin();
				passCoords[i][0] = origin[0];
				passCoords[i][1] = origin[1];
			}
		}
		double[][] passHotMap = findHotspots(convertCoordsToWeightMap(passCoords), searchRadius + 1);
		
		//Identify the hottest areas
		maxIntensity = 0;
		ArrayList<int[]> hotPassCoords = new ArrayList<int[]>();
		for (int i = 0; i < passHotMap.length; i++)
		{
			for (int j = 0; j < passHotMap[i].length; j++)
			{
				if (passHotMap[i][j] > maxIntensity)
				{
					hotPassCoords.clear();
					int[] coord = {i, j};
					hotPassCoords.add(coord);
					maxIntensity = passHotMap[i][j];
				}
				else if (passHotMap[i][j] == maxIntensity)
				{
					int[] coord = {i, j};
					hotPassCoords.add(coord);
				}
			}
		}
		
		//Search around the hot areas for actual plays
		playFound = new boolean[tempPlays.size()];
		for (int n = 0; n < hotPassCoords.size(); n++)
		{
			for (int i = -1 * searchRadius; i <= searchRadius; i++)
			{
				for (int j = -1 * searchRadius; j <= searchRadius; j++)
				{
					for (int iPlay = 0; iPlay < tempPlays.size(); iPlay++)
					{
						if (tempPlays.get(iPlay).Children.size() - 3 >= 0)
						{
							int[] origin = tempPlays.get(iPlay).Children.get(tempPlays.get(iPlay).Children.size() - 3).getOrigin();
							if ((hotPassCoords.get(n)[0] + i == origin[0]) && (hotPassCoords.get(n)[1] + j == origin[1]))
							{
								playFound[iPlay] = true;
							}
						}
					}
				}
			}
		}
		
		//Remove plays that were not found in the search radius
		for (int i = 0; i < tempPlays.size(); i++)
		{
			if (!playFound[i])
			{
				tempPlays.remove(i);
			}
		}
		
		if (tempPlays.size() == 0)
		{
			return null;
		}
		
		//Now average the locations to get the pattern skeleton
		int[][] patternCoords = new int[4][2];
		int[] point1 = {0, 0};
		int[] point2 = {0, 0};
		int[] point3 = {0, 0};
		int[] point4 = {0, 0};
		int total = 0;
		int size = tempPlays.size();
		for (int i = 0; i < size; i++)
		{
			System.out.println(i);
			System.out.println("total: " + total);
			//System.out.println(size);
			if (tempPlays.get(i).Children.size() >= 3)
			{
				point1[0] += tempPlays.get(i).Children.get(tempPlays.get(i).Children.size() - 3).getOrigin()[0];
				point1[1] += tempPlays.get(i).Children.get(tempPlays.get(i).Children.size() - 3).getOrigin()[1];
				point2[0] += tempPlays.get(i).Children.get(tempPlays.get(i).Children.size() - 2).getOrigin()[0];
				point2[1] += tempPlays.get(i).Children.get(tempPlays.get(i).Children.size() - 2).getOrigin()[1];
				point3[0] += tempPlays.get(i).Children.get(tempPlays.get(i).Children.size() - 1).getOrigin()[0];
				point3[1] += tempPlays.get(i).Children.get(tempPlays.get(i).Children.size() - 1).getOrigin()[1];
				point4[0] += tempPlays.get(i).Children.get(tempPlays.get(i).Children.size() - 1).getDestination()[0];
				point4[1] += tempPlays.get(i).Children.get(tempPlays.get(i).Children.size() - 1).getDestination()[1];
				total++;
			}
		}
		
		if (total == 0)
		{
			return null;
		}
		
		point1[0] /= total;
		point1[1] /= total;
		point2[0] /= total;
		point2[1] /= total;
		point3[0] /= total;
		point3[1] /= total;
		point4[0] /= total;
		point4[1] /= total;
		
		
		ArrayList<Action> actions = new ArrayList<Action>();
		actions.add(new Action (point1, point2, 0));
		actions.add(new Action (point2, point3, 0));
		actions.add(new Action (point3, point4, playResult));
		Play play = new Play();
		play.Children = actions;
//		patternCoords[0][0] = point1[0];
//		patternCoords[0][1] = point1[1];
//		patternCoords[1][0] = point2[0];
//		patternCoords[1][1] = point2[1];
//		patternCoords[2][0] = point3[0];
//		patternCoords[2][1] = point3[1];
//		patternCoords[3][0] = point4[0];
//		patternCoords[3][1] = point4[1];
		
		return play;
	}

}
